//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace LightweightExecutor
{
    using System;
    using System.IO;
    using System.Linq;
    using System.Text;
    using Microsoft.Research.ScientificWorkflow.TridentUtilities;
    using Microsoft.Practices.EnterpriseLibrary.Logging;

    public class Program
    {
        /// <summary>
        /// String constant for workflow id command.
        /// </summary>
        private const string WORKFLOW_COMMAND = "-wf";

        /// <summary>
        /// String constant for workflow required input parameter command.
        /// </summary>
        private const string INPUT_COMMAND = "-input";

        /// <summary>
        /// String constant for usage help text.
        /// </summary>
        private const string USAGE_HELP = "Usage:{0} {1} workflowID {2} workflowInputParametersXMLPath";

        /// <summary>
        /// Main entry point for execution.
        /// </summary>
        /// <param name="args">Command line arguments.</param>
        public static void Main(string[] args)
        {
            if (args.Length < 2 || !args.Contains(WORKFLOW_COMMAND) || (args.Length > 2 && !args.Contains(INPUT_COMMAND)))
            {
                Console.WriteLine(USAGE_HELP, AppDomain.CurrentDomain.FriendlyName, WORKFLOW_COMMAND, INPUT_COMMAND);
                Logger.Write("Invalid command line parameters passed.", "FileLogger");
                Environment.Exit(1);
            }

            try
            {
                AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomainUnhandledException);
                Guid workflowId = new Guid(args[Array.IndexOf(args, WORKFLOW_COMMAND) + 1]);
                Console.WriteLine("Starting Lightweight Executor with Workflow ID: " + workflowId, "FileLogger");
                Logger.Write("Starting Lightweight Executor with Workflow ID: " + workflowId, "FileLogger");

                string inputParameters = string.Empty;
                if (args.Contains(INPUT_COMMAND))
                {
                    string inputParameterXmlFile = args[Array.IndexOf(args, INPUT_COMMAND) + 1];
                    if (File.Exists(inputParameterXmlFile))
                    {
                        inputParameters = File.ReadAllText(inputParameterXmlFile, Encoding.ASCII);
                    }
                    else
                    {
                        Console.WriteLine("Workflow required input parameters xml does not exists. Please provide a valid path and try again.");
                        Logger.Write("Workflow required input parameters xml does not exists. Please provide a valid path and try again.", "FileLogger");
                        Environment.Exit(1);
                    }
                }

                Executor app = new Executor();
                app.Execute(workflowId, inputParameters);
            }
            catch (TridentCustomException exp)
            {
                Console.WriteLine(exp.Message);
                Logger.Write(exp.ToString(), "FileLogger");
            }
            catch (FormatException)
            {
                Console.WriteLine("Invalid workflow id", "FileLogger");
                Logger.Write("Invalid workflow id", "FileLogger");
            }
        }

        /// <summary>
        /// Method logs the unhandled exception in the app domain.
        /// </summary>
        /// <param name="sender">Object who raises the unhandled exception.</param>
        /// <param name="e">Event argument containing exception details.</param>
        private static void CurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            Console.WriteLine(e.ExceptionObject.ToString());
            Logger.Write(e.ExceptionObject.ToString(), "FileLogger");
        }
    }
}
